package com.xuzhiguang.light.gateway.core.handler;

import com.xuzhiguang.light.gateway.common.handler.AbstractGatewayRequestHandler;
import com.xuzhiguang.light.gateway.common.handler.EmptyGatewayRequestHandlerConfig;
import com.xuzhiguang.light.gateway.common.request.GatewayRequest;
import com.xuzhiguang.light.gateway.common.request.RequestContext;
import com.xuzhiguang.light.gateway.common.utils.AntPathMatcherUtils;
import com.xuzhiguang.light.gateway.core.context.GatewayContext;
import com.xuzhiguang.light.gateway.core.route.GatewayRoute;

import java.util.List;

/**
 * @author xuzhiguang
 */
public class DefaultGatewayRequestHandler extends AbstractGatewayRequestHandler<EmptyGatewayRequestHandlerConfig> {

    private static final String HANDLER_NAME = "default";

    private final GatewayFilteringHandler filteringHandler;

    private final List<GatewayRoute> routes;

    public DefaultGatewayRequestHandler(GatewayFilteringHandler filteringHandler, List<GatewayRoute> routes) {
        super(EmptyGatewayRequestHandlerConfig.class);

        this.filteringHandler = filteringHandler;
        this.routes = routes;
    }

    @Override
    public void init(EmptyGatewayRequestHandlerConfig config) {

    }

    @Override
    public void shutdown() {

    }

    public void handle(GatewayRequest gatewayRequest, RequestContext requestContext) {

        String path = gatewayRequest.getURI().getRawPath();
        GatewayRoute route = determineRoute(path);

        GatewayContext gatewayContext = new GatewayContext.Builder()
                .request(gatewayRequest)
                .requestContext(requestContext)
                .route(route)
                .build();

        if (route == null) {
            //TODO 404 error
        }

        filteringHandler.handle(gatewayContext);

        if (gatewayRequest.needRelease()) {
            requestContext.releaseRequest(gatewayRequest);
        }
    }

    private GatewayRoute determineRoute(String path) {

        for (GatewayRoute route : routes) {
            String pattern = route.getPath();
            if (AntPathMatcherUtils.match(pattern, path)) {
                return route;
            }
        }
        return null;
    }

    @Override
    public String getName() {
        return HANDLER_NAME;
    }
}
